package com.lap.framework.common.tool;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import lombok.experimental.UtilityClass;

/**
 * 日期时间工具类 - 全量版本（命名已规范化）
 *
 * <p>命名约定： - 常量：PATTERN_ + 含义（如 PATTERN_DATE_STANDARD） - 方法：format + 描述 + Date / Time / DateTime -
 * 解析：parse + 描述 + Date / DateTime - 比较：is + 条件 - 获取当前时间：current + 类型 + Str（如果返回字符串）
 */
@UtilityClass
public class DateTimeUtil {

  // ==================== 📅 常用格式常量 ====================

  /** 标准日期格式（yyyy-MM-dd） */
  public static final String PATTERN_DATE_STANDARD = "yyyy-MM-dd";

  /** 标准时间格式（HH:mm:ss） */
  public static final String PATTERN_TIME_STANDARD = "HH:mm:ss";

  /** 标准日期时间格式（yyyy-MM-dd HH:mm:ss） */
  public static final String PATTERN_DATETIME_STANDARD = "yyyy-MM-dd HH:mm:ss";

  /** 短年份紧凑日期格式（yyMMdd） */
  public static final String PATTERN_DATE_COMPACT_SHORT_YEAR = "yyMMdd";

  /** 全年份紧凑日期格式（yyyyMMdd） */
  public static final String PATTERN_DATE_COMPACT = "yyyyMMdd";

  /** 紧凑日期时间格式（yyyyMMddHHmmss） */
  public static final String PATTERN_DATETIME_COMPACT = "yyyyMMddHHmmss";

  /** 中文日期格式（yyyy年MM月dd日） */
  public static final String PATTERN_DATE_CHINESE = "yyyy年MM月dd日";

  /** 中文日期时间格式（yyyy年MM月dd日 HH时mm分ss秒） */
  public static final String PATTERN_DATETIME_CHINESE = "yyyy年MM月dd日 HH时mm分ss秒";

  // ==================== 🕐 获取当前时间 ====================

  /** 获取当前日期 */
  public static LocalDate currentDate() {
    return LocalDate.now();
  }

  /** 获取当前日期时间 */
  public static LocalDateTime currentDateTime() {
    return LocalDateTime.now();
  }

  /** 获取当前日期字符串（yyyy-MM-dd） */
  public static String currentDateStr() {
    return formatStandardDate(LocalDate.now());
  }

  /** 获取当前时间字符串（HH:mm:ss） */
  public static String currentTimeStr() {
    return formatStandardTime(LocalDateTime.now());
  }

  /** 获取当前日期时间字符串（yyyy-MM-dd HH:mm:ss） */
  public static String currentDateTimeStr() {
    return formatStandardDateTime(LocalDateTime.now());
  }

  /** 获取当前时间戳字符串（yyyyMMddHHmmss） */
  public static String currentTimestampStr() {
    return formatCompactDateTime(LocalDateTime.now());
  }

  // ==================== 📆 时间格式转换 ====================

  /** 格式化标准日期（yyyy-MM-dd） */
  public static String formatStandardDate(LocalDate date) {
    return date.format(DateTimeFormatter.ofPattern(PATTERN_DATE_STANDARD));
  }

  /** 格式化标准时间（HH:mm:ss） */
  public static String formatStandardTime(LocalDateTime dateTime) {
    return dateTime.format(DateTimeFormatter.ofPattern(PATTERN_TIME_STANDARD));
  }

  /** 格式化标准日期时间（yyyy-MM-dd HH:mm:ss） */
  public static String formatStandardDateTime(LocalDateTime dateTime) {
    return dateTime.format(DateTimeFormatter.ofPattern(PATTERN_DATETIME_STANDARD));
  }

  /** 格式化短年份紧凑日期（yyMMdd） */
  public static String formatCompactShortYearDate(LocalDate date) {
    return date.format(DateTimeFormatter.ofPattern(PATTERN_DATE_COMPACT_SHORT_YEAR));
  }

  /** 格式化全年份紧凑日期（yyyyMMdd） */
  public static String formatCompactDate(LocalDate date) {
    return date.format(DateTimeFormatter.ofPattern(PATTERN_DATE_COMPACT));
  }

  /** 格式化紧凑日期时间（yyyyMMddHHmmss） */
  public static String formatCompactDateTime(LocalDateTime dateTime) {
    return dateTime.format(DateTimeFormatter.ofPattern(PATTERN_DATETIME_COMPACT));
  }

  /** 格式化中文日期（yyyy年MM月dd日） */
  public static String formatChineseDate(LocalDate date) {
    return date.format(DateTimeFormatter.ofPattern(PATTERN_DATE_CHINESE));
  }

  /** 格式化中文日期时间（yyyy年MM月dd日 HH时mm分ss秒） */
  public static String formatChineseDateTime(LocalDateTime dateTime) {
    return dateTime.format(DateTimeFormatter.ofPattern(PATTERN_DATETIME_CHINESE));
  }

  // ==================== 📥 字符串解析 ====================

  /** 解析标准日期字符串（yyyy-MM-dd） */
  public static LocalDate parseStandardDate(String dateStr) {
    return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(PATTERN_DATE_STANDARD));
  }

  /** 解析标准日期时间字符串（yyyy-MM-dd HH:mm:ss） */
  public static LocalDateTime parseStandardDateTime(String dateTimeStr) {
    return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(PATTERN_DATETIME_STANDARD));
  }

  // ==================== 📊 时间比较 ====================

  /** 判断两个日期是否相等 */
  public static boolean isSameDate(LocalDate date1, LocalDate date2) {
    return date1.isEqual(date2);
  }

  /** 判断日期是否在今天之前 */
  public static boolean isBeforeToday(LocalDate date) {
    return date.isBefore(LocalDate.now());
  }

  /** 判断日期是否在今天之后 */
  public static boolean isAfterToday(LocalDate date) {
    return date.isAfter(LocalDate.now());
  }

  /** 判断日期时间是否在当前时间之前 */
  public static boolean isBeforeNow(LocalDateTime dateTime) {
    return dateTime.isBefore(LocalDateTime.now());
  }

  /** 判断日期时间是否在当前时间之后 */
  public static boolean isAfterNow(LocalDateTime dateTime) {
    return dateTime.isAfter(LocalDateTime.now());
  }

  /** 判断日期是否在指定范围内 */
  public static boolean isBetween(LocalDate date, LocalDate startDate, LocalDate endDate) {
    return !date.isBefore(startDate) && !date.isAfter(endDate);
  }

  /** 计算两个日期之间的天数差 */
  public static long daysBetween(LocalDate startDate, LocalDate endDate) {
    return ChronoUnit.DAYS.between(startDate, endDate);
  }

  /** 计算两个日期时间之间的小时差 */
  public static long hoursBetween(LocalDateTime startDateTime, LocalDateTime endDateTime) {
    return ChronoUnit.HOURS.between(startDateTime, endDateTime);
  }

  /** 计算两个日期时间之间的分钟差 */
  public static long minutesBetween(LocalDateTime startDateTime, LocalDateTime endDateTime) {
    return ChronoUnit.MINUTES.between(startDateTime, endDateTime);
  }

  // ==================== ➕ 时间加减 ====================

  /** 日期加减天数 */
  public static LocalDate plusDays(LocalDate date, int days) {
    return date.plusDays(days);
  }

  /** 日期加减天数后格式化为字符串 */
  public static String plusDaysAndFormat(LocalDate date, int days) {
    return formatStandardDate(date.plusDays(days));
  }

  /** 日期加减月数 */
  public static LocalDate plusMonths(LocalDate date, int months) {
    return date.plusMonths(months);
  }

  /** 日期加减年数 */
  public static LocalDate plusYears(LocalDate date, int years) {
    return date.plusYears(years);
  }

  /** 日期时间加减小时 */
  public static LocalDateTime plusHours(LocalDateTime dateTime, int hours) {
    return dateTime.plusHours(hours);
  }

  /** 日期时间加减分钟 */
  public static LocalDateTime plusMinutes(LocalDateTime dateTime, int minutes) {
    return dateTime.plusMinutes(minutes);
  }

  /** 日期时间加减秒数 */
  public static LocalDateTime plusSeconds(LocalDateTime dateTime, int seconds) {
    return dateTime.plusSeconds(seconds);
  }

  // ==================== 🛠 实用方法 ====================

  /** 获取今天的开始时间（00:00:00） */
  public static LocalDateTime startOfToday() {
    return LocalDate.now().atStartOfDay();
  }

  /** 获取今天的结束时间（23:59:59） */
  public static LocalDateTime endOfToday() {
    return LocalDate.now().atTime(23, 59, 59);
  }

  /** 获取指定日期的开始时间 */
  public static LocalDateTime startOfDay(LocalDate date) {
    return date.atStartOfDay();
  }

  /** 获取指定日期的结束时间 */
  public static LocalDateTime endOfDay(LocalDate date) {
    return date.atTime(23, 59, 59);
  }

  /** 获取年龄（基于生日） */
  public static int calculateAge(LocalDate birthday) {
    return (int) ChronoUnit.YEARS.between(birthday, LocalDate.now());
  }

  /** 判断是否为闰年 */
  public static boolean isLeapYear(LocalDate date) {
    return date.isLeapYear();
  }
}
